library IEEE;
use IEEE.std_logic_1164.all;

entity coder is
    port(clk: in std_logic;
         rst: in std_logic;
         D_I: in std_logic;
         D_O: out std_logic);
end coder;

architecture behaviour of coder is
    type miller_states is (s0, s1, s2, s3, s4);
    signal clk_4: std_logic := '0';
    signal state: miller_states := s1;
    signal defdata: std_logic;
begin
    process(clk)
        variable count: integer := 0;
        begin       
 
             
            if(count = 4 and clk'event and clk = '1') then
                count := 0;
                clk_4 <= not clk_4;
            end if;
            
            if(clk'event and clk = '1') then
               count := count + 1;
            end if;
            
            
        end process;
   
   process(D_I, clk_4)
       begin
           case state is
           when s0 =>
               if(D_I'event and D_I = '0') then
                   state <= s1;
                   defdata <= '0';
               elsif(D_I'event and D_I = '1) then
                   state <= s4;
                   defdata <= '0';
               end if;
               
                         
           when s1 =>
               if((D_I = '0' and clk_4'event and clk_4 = '0')) then
                  state <= s4;
                  defdata <= '0';
               elsif(D_I = '1' and clk_4'event and clk_4 = '0') then
                  state <= s2;
                  defdata <= '1';
               elsif(clk_4'event and clk_4 = '1') then
                   
               end if;
           when s2 =>
               if(D_I = '0' and clk_4'event and clk_4 = '0') then
                  state <= s4;
                  defdata <= '0';
               elsif((D_I = '1' and clk_4'event and clk_4 = '0')) then
                  state <= s3;
                  defdata <= '0';
               elsif(clk_4'event and clk_4 = '1') then
                   defdata <= '0';
               end if;
               
           when s3 =>
               if(D_I = '0' and clk_4'event and clk_4 = '0') then
                  state <= s1;
                  defdata <= '1';
               elsif((D_I = '1' and clk_4'event and clk_4 = '0')) then
                  state <= s2;
                  defdata <= '1';
               elsif(clk_4'event and clk_4 = '1') then
                  defdata <= '1';
               end if;
            
           when s4 =>
               if((D_I = '0' and clk_4'event and clk_4 = '0')) then
                  state <= s1;
                  defdata <= '1';
               elsif(D_I = '1' and clk_4'event and clk_4 = '0') then
                  state <= s3;
                  defdata <= '0';
               elsif(clk_4'event and clk_4 = '1') then
                   
               end if;
               
           end case;
            
       end process;
       
       process(clk)
           variable count : integer := 0;
           begin
            
           if((count = 8) and clk'event and clk = '1') then
               count := 0;
           end if;   
               
            if((count = 4) and (state = s2 or state = s3) and clk'event and clk = '1') then
                if(defdata = '1') then
                    D_O <= not clk;
                else
                    D_O <= clk;
                end if;
            else
               if(defdata = '1') then
                    D_O <= clk;
                else
                    D_O <= not clk;
                end if;
           end if;
           

            
           if(clk'event and clk = '1') then
               count := count + 1;
            end if;


           end process;
   
end architecture behaviour;